package com.windsea.relationshipmining.services;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import com.windsea.relationshipmining.api.ContactApi;
import com.windsea.relationshipmining.database.DBUserData;

import android.content.ContentValues;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;

/** This class detects outgoing & incoming SMS messages. **/
public class SMSWatcher extends ContentObserver {
	// Initialize constants and variables
	public static final String TAG = "SMSSender";
	public static final String type = "Outgoing";
	private Context context;
	SimpleDateFormat formatdatetime = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");

	/**
	 * Constructor needed for content observers.
	 * 
	 * @param handler
	 * @param context
	 */
	public SMSWatcher(Handler handler, Context context) {
		super(handler);
		this.context = context;
	}

	/**
	 * This method handles the content observer change notifications.
	 * 
	 * @param selfChange
	 */
	@Override
	public void onChange(boolean selfChange) {
		super.onChange(selfChange);
//		Log.d(TAG, "Onchange");
		querySMSLog();
	}

	/**
	 * This method attempts to find newly logged outgoing SMS messages.
	 */
	private void querySMSLog() {
		// Initialize SMS content provider URI (undocumented)
		Uri uriSMS = Uri.parse("content://sms");

		// Query for SMS id, body, address, date, and type
		String[] smsProj = new String[] { "_id", "thread_id", "body",
				"address", "date", "type" };
		Cursor smsCursor = null;

		try {
			smsCursor = context.getContentResolver().query(uriSMS, smsProj,
					null, null, null);
		} catch (Exception e) {
//			Log.e(TAG, "Unable to query URI: " + uriSMS.toString());
			return;
		}

		// Parse query results
		if (smsCursor == null) {
//			Log.e(TAG, "Unable to query SMS content provider");
			return;
		}

		if (smsCursor.moveToFirst() && smsCursor.getCount() > 0) {
			int messageID = -1;
			long then = -1;
			String body = null;
			String address = null;
			String datetime = null;
			int threadId = -1;
			int smsType = -1;

			// Get SMS message
			try {
				messageID = smsCursor.getInt(smsCursor.getColumnIndex("_id"));
				threadId = smsCursor.getInt(smsCursor
						.getColumnIndex("thread_id"));
				body = smsCursor.getString(smsCursor.getColumnIndex("body"));
				address = ContactApi.phoneNumberProcess(smsCursor
						.getString(smsCursor.getColumnIndex("address")));
//				Log.d(TAG, address);
				then = smsCursor.getLong(smsCursor.getColumnIndex("date"));
				datetime = formatdatetime.format(then);
				smsType = Integer.valueOf(smsCursor.getString(smsCursor
						.getColumnIndex("type")));

			} catch (Exception e) {
//				Log.e(TAG, "Unable to log SMS EXCEPTION");
				return;
			}

			if (messageID == -1 || body == null || address == null
					|| datetime == null || smsType == -1) {
//				Log.e(TAG, "Unable to log SMS");
				return;
			}

			String strSmsType = typeSMS(smsType);

			// Get contact id
			String contactId = ContactApi.contactIdFinder(address, context);
			// Log any newly logged outgoing SMS messages
			Calendar cal = Calendar.getInstance();
			cal.add(Calendar.SECOND, -5);
			long fiveSecondsAgo = cal.getTimeInMillis();
			// MESSAGE_TYPE_ALL = 0;
			// MESSAGE_TYPE_INBOX = 1;
			// MESSAGE_TYPE_SENT = 2;
			// MESSAGE_TYPE_DRAFT = 3;
			// MESSAGE_TYPE_OUTBOX = 4;
			// MESSAGE_TYPE_FAILED = 5; // for failed outgoing messages
			// MESSAGE_TYPE_QUEUED = 6; // for messages to send later

			if (new Date(then).getTime() > fiveSecondsAgo && strSmsType != null
					&& contactId != null) {
				// Check to make sure sms is not a duplicate
				DBUserData dbUserData = new DBUserData(context);
				dbUserData.open();

				Cursor cursor = null;
				try {
					cursor = dbUserData.checkSMS(messageID);
				} catch (Exception e) {
//					Log.e(TAG, "Unable to query sms table, non-checked");
					dbUserData.close();
					return;
				}

				if (cursor == null) {
//					Log.e(TAG, "Unable to query sms table");
					dbUserData.close();
					return;
				}

				if (cursor.getCount() == 0) {
					// Insert new outgoing sms
					dbUserData.insertSMS(messageID, datetime, threadId, contactId,
							body.length(), strSmsType);
					Log.i(TAG, "SMS Type: " + strSmsType + " Number: "
							+ address + " Date: " + datetime + " Body: " + body
							+ " ID: " + messageID);
				}
				dbUserData.close();
				cursor.close();
			}
		}
	}

	public String typeSMS(int type) {
		String strType = null;
		switch (type) {
		case 2:
			strType = "Outgoing";
			break;
		case 1:
			strType = "Incoming";
			break;
		default:

			break;
		}
		return strType;
	}
}
